package ij.umasuo.gui.working;

import ij.ImagePlus;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.ImageObserver;
/**
 * the image canvas is the component to show the 
 * @author liuquan
 * @date 2013-08-17
 * @version 1.0
 *
 */
public class MyImageCanvas extends Canvas implements ImageObserver,KeyListener,MouseListener,MouseMotionListener {

	private static final long serialVersionUID = 1L;
	private boolean isROI = false;//show if we are using the ROI model
	private Rectangle roi = new Rectangle();
	private float zoomDegree = 1.0f;// the zoom degree, zoom in or zoom out
	private int driftX = 0, driftY = 0;//the drift of the image,only used when we are draging
	private Rectangle ctrPanel = new Rectangle();//the control pannel
	private int startX = 0, startY = 0;//use for dragging
	private boolean isHand = true;//in hand model, we will move the image in the pannel
	private Image image = null;
	private Image bufferImage = null;
	private int centerX,centerY;//the drift of the image center
	
	public MyImageCanvas(){
		this.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent arg0) {
				resized();
			}
		});
		this.addKeyListener(this);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
//		this.setBackground(Color.BLACK);
		ImagePlus imp = new ImagePlus("D:\\Feb.26\\Test4\\Cox4_cccp_1H_Cy5_HeLa.tif");
		image = imp.getImage();
	}
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		
		if(image!=null){//draw the image
			int width = (int)(this.getWidth()*zoomDegree);
			int height = (int)(this.getHeight()*zoomDegree);
			int x = (width - this.getWidth())/2;
			int y = (height - this.getHeight())/2;
			int w = (int)(this.getWidth()*zoomDegree - this.getWidth())/2;
			int h = (int)(this.getHeight()*zoomDegree - this.getHeight())/2;
			if(Math.abs(centerX) > w){
				centerX = w;
			}
			if(Math.abs(centerY) > h){
				centerY = h;
			}
			g.drawImage(image, -x + centerX + driftX, -y + centerY + driftY,width,height, null);
			g.drawImage(image, 1, 1, 100, 100, null);//draw the thumbnail
		}
		
		drawCtrRect(g);
		drawROI(g);
	}
	
	/**
	 * draw the control panel
	 * @param g
	 */
	private void drawCtrRect(Graphics g){
		//draw the out frame
		g.setColor(Color.WHITE);
		g.drawRect(1, 1, 100, 100);
		//draw the internal frame
		g.drawRect(ctrPanel.x, ctrPanel.y, ctrPanel.width, ctrPanel.height);
	}
	
	/**
	 * draw the ROI rectangle
	 * @param g
	 */
	private void drawROI(Graphics g){
		g.setColor(Color.WHITE);
		g.drawRect(roi.x, roi.y, roi.width, roi.height);
	}

	/**
	 * enable or disable roi model
	 * @param isROI
	 */
	public void enableROI(boolean isROI){
		this.isROI = isROI;
	}

	/**
	 * resize the canvas
	 */
	private void resized(){
		this.repaint();
	}
	
	/**
	 * draw a new image on the canvas
	 * @param image
	 */
	public void drawImage(Image image){
		if(image != null){
			this.image = image;
		}
		repaint();
	}
	
	public void setImage(Image image){
		if(image != null){
			this.image = image;
		}
	}
	
	@Override
	public void keyPressed(KeyEvent keyEvent) {
		int keyCode = keyEvent.getKeyCode();
		if(keyCode == KeyEvent.VK_EQUALS){
			zoomDegree += 0.1;
		}else if(keyCode == KeyEvent.VK_MINUS){
			zoomDegree -= 0.1;
			if(zoomDegree < 1.0f){
				zoomDegree = 1.0f;
			}
		}
		ctrPanel.width = (int)(100/zoomDegree);
		ctrPanel.height = (int)(100/zoomDegree);
		this.repaint();
	}


	@Override
	public void keyReleased(KeyEvent arg0) {
		
	}

	@Override
	public void keyTyped(KeyEvent keyEvent) {

	}

	@Override
	public void mouseClicked(MouseEvent arg0) {
		int x = arg0.getX();
		int y = arg0.getY();
		if(x<100&&y<100){
			ctrPanel.x = x- ctrPanel.width/2;
			ctrPanel.y = y- ctrPanel.height/2;
			if(ctrPanel.x <0){
				ctrPanel.x = 0;
			}
			if(ctrPanel.x + ctrPanel.width > 100){
				ctrPanel.x = 100 - ctrPanel.width;
			}
			if(ctrPanel.y <0){
				ctrPanel.y = 0;
			}
			if(ctrPanel.y + ctrPanel.height > 100){
				ctrPanel.y = 100 - ctrPanel.height;
			}
		}
	}


	@Override
	public void mouseEntered(MouseEvent arg0) {
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		startX = arg0.getX();
		startY = arg0.getY();
		if(startX > 0 && startX <100 && startY>0 && startY <100){
			
		}else{
			if(isROI){
				roi.x = startX;
				roi.y = startY;
				roi.width = 0;
				roi.height = 0;
			}
		}
		this.repaint();
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		int x = arg0.getX();
		int y = arg0.getY();
		
		if(isROI){
			roi.width = x - startX;
			roi.height = y - startY;
		}else if(isHand){
			centerX += driftX;
			centerY += driftY;
			driftX = 0;
			driftY = 0;
		}
		this.repaint();
//		isROI = false;
	}

	@Override
	public void mouseDragged(MouseEvent arg0) {
		int x = arg0.getX();
		int y = arg0.getY();
		if(x >=0 && x<= 100 && y >= 0 && y<= 100){
			//move the control panel
		}else{
			if(isROI){
				roi.width = x - startX;
				roi.height = y - startY;
			}else if(isHand){
				driftX = x-startX;
				driftY = y-startY;
			}
		}
		this.repaint();
	}

	@Override
	public void mouseMoved(MouseEvent arg0) {
		int x = arg0.getX();
		int y = arg0.getY();
		if(x>0 && x<100 && y>0 && y< 100){
			this.setCursor(new Cursor(Cursor.HAND_CURSOR));
		}else{
			this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		}
	}
	
}
